#ifndef _BUOLA_GUI_CWINDOWMANAGER_H_
#define _BUOLA_GUI_CWINDOWMANAGER_H_

#include <buola/gui.h>

#include <buola/gui/cwindow.h>
#include <buola/app/ceventloop.h>
#include <buola/algorithm/container.h>

#include <set>

namespace buola { namespace gui {
    
///\ingroup gui widgets
///@{

class CWindowManager : public CLoopFunction
{
public:
    CWindowManager();
    
    virtual bool OnLoopFunction();

    void FreezeModal(CWindow *pWindow,bool pRepeat=false);
    void OnPhysicalMouse(CMouseEvent *pE,CPhysicalWindow *pWindow);
    void OnPhysicalKey(CKeyEvent *pE);
    void OnPhysicalExpose(CPhysicalWindow *pWindow,const CRect_d &pRect,bool pMore,bool pSendEvent);
    void OnPhysicalGeometry(CPhysicalWindow *pWindow,const CPoint_d &pPos,const CSize_d &pSize);
    void OnPhysicalMap(CPhysicalWindow *pWindow,bool pMapped);
    void OnPhysicalCloseWindow(CPhysicalWindow *pWindow);
    void OnPhysicalActivate(CPhysicalWindow *pWindow,bool pActive);
    void OnPointerChanged(CWindow *pWindow);
    
    void Add(CWindow *pWindow)          {   mAll.push_back(pWindow);            }
    void Remove(CWindow *pWindow)       {   erase_first_equal(mAll,pWindow);    }
    
    const std::vector<CWindow*> &All()  {   return mAll;    }

    CWindow *ActiveWindow()     {   return mActiveWindow;       }
    CWindow *FocusWindow()      {   return mFocusWindow;        }
    CWindow *GrabFocusWindow()  {   return mGrabFocusWindow;    }
    
    void ModalLoop(CWindow *pFrame);
    void ExitModal(CWindow *pWindow);
    
    void SetGrabFocusTo(CWindow *pWindow);
    void SetFocusTo(CWindow *pWindow);

    std::set<CWindow*> mLayout;
    std::set<CWindow*> mRefresh;
    
    std::vector<CWindow*> mAll;

private:
    CWindow *mPointerWindow;
////////////////////
// grab and focus
//
    CWindow *mModalFrame;
    CWindow *mActiveWindow;
    CWindow *mFocusWindow;
    CWindow *mGrabFocusWindow;
    CWindow *mDragWindow; ///< the window for which a drag was initiated and should receive move events

    std::vector<CWindow*> mExitModal;
    bool mModalLoopExit;
};

///@}

/*namespace gui*/ } /*namespace buola*/ }

#endif
